package com.fsd.admin.service.impl;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.json.JSONObject;

import com.fsd.admin.entity.A_LoginInfo;
import com.fsd.admin.model.A_Employee;
import com.fsd.admin.model.F_flownode;
import com.fsd.admin.model.F_flownodeterm;
import com.fsd.admin.model.F_flowobject;
import com.fsd.admin.model.F_flowproject;
import com.fsd.admin.model.F_flowrecord;
import com.fsd.admin.service.F_flownodeService;
import com.fsd.admin.service.F_flownodetermService;
import com.fsd.admin.service.F_flowobjectService;
import com.fsd.admin.service.F_flowprojectService;
import com.fsd.admin.service.F_flowrecordService;
import com.fsd.admin.service.WorkFlowService;
import com.fsd.core.common.BusinessException;
import com.fsd.core.util.Config;
import com.fsd.core.util.SpringContextHolder;


public abstract class WorkFlowServiceImpl<T, PK extends Serializable> extends MainServiceImpl<T, PK> implements WorkFlowService{

	private static final Logger log = Logger.getLogger(WorkFlowServiceImpl.class);
	//数据处理状态
	public static final String sjds1 = F_flowrecordServiceImpl.sjds1;
	public static final String sjds2 = F_flowrecordServiceImpl.sjds2;
	
    @Resource(name = "f_flowobjectServiceImpl")
	private F_flowobjectService flowObjectService;
    @Resource(name = "f_flowprojectServiceImpl")
	private F_flowprojectService flowProjectService;
    @Resource(name = "f_flownodeServiceImpl")
	private F_flownodeService flowNodeService;
    @Resource(name = "f_flownodetermServiceImpl")
	private F_flownodetermService flowNodeTermService;
    @Resource(name = "f_flowrecordServiceImpl")
	private F_flowrecordService flowRecordService;
    
    /**
     * 检查工作流是否启动
     * @param flowCode
     * @param companyID
     * @return boolean
     * @throws Exception
     */
    public boolean checkFlowProjectQYZT(String flowCode, String companyID) throws Exception{
    	F_flowproject project = flowProjectService.getObjectByCode(flowCode, companyID);
		if (project == null){
			return false;
		}
		if (!project.getStatus().equals(F_flowprojectServiceImpl.fpqy1)){
			return false;
		}
		return true;
    }
	
    /**
	 * 提交保存工作流程对象
	 * @param flowCode 流程编码
	 * @param objID 数据对象ID
	 * @param typeID 数据类型ID
	 * @param typeName 数据类型名称
	 * @param objCode 数据对象Code
	 * @param objDepict 数据对象描述
	 * @param objJson 数据对象Json数据
	 * @param companyID 数据对象所属单位
	 * @param realName 申请人姓名
	 * @param isCheck 是否检查工作流程存在
	 * @throws Exception
	 */
    public void saveWorkFlowSubmit(String flowCode, String objID, String typeID, String typeName, String objCode, 
    		String objDepict, Map<String, Object> mapJson, String companyID, String realName, boolean isCheck) throws Exception{
    	A_LoginInfo loginInfo = new A_LoginInfo();
    	A_Employee employee = new A_Employee();
    	employee.setCompanyid(companyID);
    	employee.setRealname(realName);
    	loginInfo.setEmployee(employee);
    	this.saveWorkFlowSubmit(flowCode, objID, typeID, typeName, objCode, objDepict, mapJson, loginInfo, isCheck);
    }
	/**
	 * 提交保存工作流程对象
	 * @param flowCode 流程编码
	 * @param objID 数据对象ID
	 * @param typeID 数据类型ID
	 * @param typeName 数据类型名称
	 * @param objCode 数据对象Code
	 * @param objDepict 数据对象描述
	 * @param objJson 数据对象Json数据
	 * @param loginInfo 当前操作人
	 * @param isCheck 是否检查工作流程存在
	 * @throws Exception
	 */
    protected void saveWorkFlowSubmit(String flowCode, String objID, String typeID, String typeName, String objCode, 
    		String objDepict, Map<String, Object> mapJson, A_LoginInfo loginInfo, boolean isCheck) throws Exception{
    	if (mapJson == null || mapJson.size() == 0 || !mapJson.containsKey("data")){
			throw new BusinessException("原始数据未找到，无法Json转换保存");
    	}
    	String objJson = net.sf.json.JSONObject.fromObject(mapJson).toString();
    	F_flowproject project = flowProjectService.getObjectByCode(flowCode, loginInfo.getEmployee().getCompanyid());
		if (project == null){
			if (isCheck){
				throw new BusinessException("工作流程项目不存在，项目编码：“" + flowCode + "”!");
			}else{
				this.sysLogService.saveObject(Config.LOGTYPEQT, "工作流程项目不存在，项目编码：“" + flowCode + "”!", loginInfo.getEmployee(), WorkFlowServiceImpl.class);
				return;
			}
		}
		if (!project.getStatus().equals(F_flowprojectServiceImpl.fpqy1)){
			if (isCheck){
				throw new BusinessException("工作流程项目已停止，项目编码：“" + flowCode + "”、项目名：“" + project.getName() + "”!");
			}else{
				this.sysLogService.saveObject(Config.LOGTYPEQT, "工作流程项目已停止，项目编码：“" + flowCode + "”、项目名：“" + project.getName() + "”!", loginInfo.getEmployee(), WorkFlowServiceImpl.class);
				return;
			}
		}
		if (!project.getAcceptcode().equals(F_flowprojectServiceImpl.fpslqy1)){
			if (isCheck){
				throw new BusinessException("工作流程项目受理已停止，项目编码：“" + flowCode + "”、项目名：“" + project.getName() + "”!");
			}else{
				this.sysLogService.saveObject(Config.LOGTYPEQT, "工作流程项目受理已停止，项目编码：“" + flowCode + "”、项目名：“" + project.getName() + "”!", loginInfo.getEmployee(), WorkFlowServiceImpl.class);
				return;
			}
		}
		F_flownode node = flowNodeService.getObjectByPreviousID(project.getId());
		if (node == null){
			if (isCheck){
				throw new BusinessException("工作流程节点不存在，项目编码：“" + project.getCode() + "”、项目名：“" + project.getName() + "”!");
			}else{
				this.sysLogService.saveObject(Config.LOGTYPEQT, "工作流程节点不存在，项目编码：“" + project.getCode() + "”、项目名：“" + project.getName() + "”!", loginInfo.getEmployee(), WorkFlowServiceImpl.class);
				return;
			}
		}
		List<F_flownodeterm> termList = flowNodeTermService.getObjectListByNodeID(node.getId());
		if (termList == null || termList.size() == 0){
			if (isCheck){
				throw new BusinessException("工作流程节点条件不存在，节点ID：“" + node.getId() + "”、节点名：“" + node.getName() + "”!");
			}else{
				this.sysLogService.saveObject(Config.LOGTYPEQT, "工作流程节点条件不存在，节点ID：“" + node.getId() + "”、节点名：“" + node.getName() + "”!", loginInfo.getEmployee(), WorkFlowServiceImpl.class);
				return;
			}
		}
		WorkFlowService operateClass = (WorkFlowService) SpringContextHolder.getBean(project.getOperatepath());
		if (operateClass == null){
			throw new BusinessException("工作流程业务操作类不存在，无法保存！");
		}

		//流程对象
    	F_flowobject flowObj = flowObjectService.getObjectByDataObjId(objID);
    	if (flowObj == null){
    		flowObj = new F_flowobject();
    		flowObj.setId(this.getUUID());
    		flowObj.setApplydate(this.getData());
    		flowObjectService.save(flowObj);
    	}
		flowObj.setCompanyid(loginInfo.getEmployee().getCompanyid());
		flowObj.setProjectid(project.getId());
		flowObj.setProjectcode(project.getCode());
		flowObj.setProjectname(project.getName());
		flowObj.setNodeid(node.getId());
		flowObj.setNodename(node.getName());
		flowObj.setDataobjectid(objID);
		flowObj.setDataobjectname("");
		flowObj.setDatatypeid(typeID);
		flowObj.setDatatypename(typeName);
		flowObj.setCode(objCode);
		flowObj.setBranchid(loginInfo.getEmployee().getBranchid());
		flowObj.setBranchname(loginInfo.getEmployee().getBranchname());
		flowObj.setEmployeeid(loginInfo.getEmployee().getId());
		flowObj.setEmployeename(loginInfo.getEmployee().getRealname());
		flowObj.setDatadepict(objDepict);
		flowObj.setFlowstatus(F_flowobjectServiceImpl.folcz1);
		flowObj.setFlowstatusname(F_flowobjectServiceImpl.folcz2);
		flowObj.setWindowname(project.getWindowname());
		flowObj.setWindowpath(project.getWindowpath());
		flowObj.setObjectjson(objJson);
		
		String flowRecordID = this.getUUID();
		F_flowrecord record = null;
		//自动节点
		if (node.getNodetype().equals(F_flownodeServiceImpl.fnzdp)){
			JSONObject jObj = new JSONObject(objJson);
			JSONObject jData = jObj.getJSONObject("data");
			//自动节点处理过程
			StringBuilder builder = new StringBuilder(flowRecordID);
			node = this.flowRecordService.executeAutoNode(builder, flowObj, project, 
					loginInfo, this, node, null, jData);
			flowRecordID = builder.toString();
			if (node.getNodetype().equals(F_flownodeServiceImpl.fnjsd)){
				record = this.flowRecordService.getObjectByNextRecordId(flowRecordID);
				flowRecordID = record.getId();
			}
		}
		flowObj.setRecordid(flowRecordID);
		flowObjectService.update(flowObj);
		
		//流程开始修改原对象流程状态
		this.saveWorkFlowStart(objID, F_flowrecordServiceImpl.sjlc1, F_flowrecordServiceImpl.sjlc2, loginInfo);
		//结束节点
		if (node.getNodetype().equals(F_flownodeServiceImpl.fnjsd)){
			flowObj.setFlowstatus(F_flowobjectServiceImpl.fowc1);
			flowObj.setFlowstatusname(F_flowobjectServiceImpl.fowc2);
			flowObj.setNodeid(node.getId());
			flowObj.setNodename(node.getName());
			this.flowObjectService.update(flowObj);
			//完成流程全过程
			operateClass.saveWorkFlowFinish(record, null, 
					F_flowrecordServiceImpl.sjwc1, F_flowrecordServiceImpl.sjwc2, loginInfo);
			return;
		}
		//流程记录保存
		this.flowRecordService.saveRecordAndDealt(flowRecordID, flowObj, project, node, loginInfo);
	}
}
